package drds.plus.sql_process.abstract_syntax_tree.execute_plan.dml;

import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlanImpl;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.query.Query;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import drds.plus.sql_process.utils.OptimizerUtils;

import java.util.ArrayList;
import java.util.List;

public abstract class Put<T extends IPut> extends ExecutePlanImpl<T> implements IPut<T> {

    protected Query query;
    protected List<Item> itemList;
    protected List<Object> valueList;
    protected PutType putType;
    protected String indexName; // 逻辑索引信息
    protected String tableName; // 真实表名


    protected List<List<Object>> valueListList;
    protected boolean isValueListList;
    protected List<Integer> batchIndexList = new ArrayList(0);

    public Put() {
        putType = PutType.replace;
    }

    public Query getQuery() {
        return query;
    }

    public void setQueryTree(Query query) {
        this.query = query;

    }

    public void setUpdateItemList(List<Item> itemList) {
        this.itemList = itemList;

    }

    public List<Item> getUpdateItemList() {
        return itemList;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;

    }

    public String getTableName() {
        return this.tableName;
    }

    public void setUpdateValues(List<Object> values) {
        this.valueList = values;

    }

    public List<Object> getUpdateValues() {
        return valueList;
    }

    public PutType getPutType() {
        return putType;
    }

    public void setIndexName(String indexName) {
        this.indexName = indexName;

    }

    public String getIndexName() {
        return indexName;
    }


    public List<List<Object>> getValueListList() {
        return valueListList;
    }

    public void setValueListList(List<List<Object>> multiValues) {
        this.valueListList = multiValues;

    }

    public boolean isValueListList() {
        return isValueListList;
    }

    public void setIsValueListList(boolean isMultiValues) {
        this.isValueListList = isMultiValues;

    }

    public int getValueListListSize() {
        if (this.isValueListList) {
            return this.valueListList.size();
        } else {
            return 1;
        }
    }

    public List<Object> getValueList(int index) {
        if (this.isValueListList) {
            return this.valueListList.get(index);
        }

        return this.valueList;
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        if (this instanceof Insert) {
            executePlanVisitor.visit((Insert) this);
        } else if (this instanceof Delete) {
            executePlanVisitor.visit((Delete) this);
        } else if (this instanceof Update) {
            executePlanVisitor.visit((Update) this);
        } else if (this instanceof Replace) {
            executePlanVisitor.visit((Replace) this);
        }
    }

    public void copySelfTo(IPut put) {
        put.setQueryTree((Query) this.query.copy());
        put.setUpdateItemList(OptimizerUtils.copySelectItemList(itemList));
        put.setUpdateValues(OptimizerUtils.copyValues(valueList));
        put.setIndexName(this.indexName);
        put.setTableName(this.tableName);
        put.setIsValueListList(isValueListList);
        if (valueListList != null) {
            List<List<Object>> newMultiValues = new ArrayList<List<Object>>();
            for (List<Object> valueList : valueListList) {
                newMultiValues.add(OptimizerUtils.copyValues(valueList));
            }

            put.setValueListList(newMultiValues);
        }

        put.setBatchIndexList(new ArrayList(this.batchIndexList));
    }


    public List<Integer> getBatchIndexList() {
        return this.batchIndexList;
    }

    public void setBatchIndexList(List<Integer> batchIndexList) {
        this.batchIndexList = batchIndexList;

    }


}
